// AboutDlg.cpp : implementation of the CDraftsDlg class
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#ifdef WIN32_PLATFORM_PSPC
#include "resourceppc.h"
#else
#include "resourcesp.h"
#endif
#include "membersdlg.h"
#include "memberinfodlg.h"
#include "utils.h"
#include "GroupsDlg.h"

CMembersDlg::CMembersDlg(UINT GroupId, CString GroupName)
    : m_GroupId(GroupId)
    , m_GroupName(GroupName)
    , m_DisplayNumber(false)
{
    ATLASSERT(m_GroupName.IsEmpty() == false);
}

LRESULT CMembersDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
    AtlCreateMenuBar(m_hWnd, IDM_CONTACTS_MENU);

#ifdef WIN32_PLATFORM_WFSP
    if (hMenuBar != NULL)
        AtlActivateBackKey(hMenuBar);
#endif

    BOOL Ret = m_ImageList.Create(24, 24, ILC_COLORDDB | ILC_MASK, 2, 0);
    ATLASSERT(Ret == TRUE);

    CIcon icon;
    icon.LoadIcon(IDI_MEMBER, 24, 24);
    int Result = m_ImageList.AddIcon(icon);
    ATLASSERT(Result != -1);
    icon.DestroyIcon();

    m_List.Attach(GetDlgItem(IDC_LIST));
    m_List.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT);
    m_List.SetImageList(m_ImageList, LVSIL_SMALL);

    CRect r;
    m_List.GetClientRect(&r);
    m_List.InsertColumn(INDEX_NAME, NULL, LVCFMT_LEFT, r.Width());
    m_List.InsertColumn(INDEX_OP, NULL, LVCFMT_RIGHT, r.Width());

    CString Load;
    Load.LoadString(IDS_MEMBERS_OF);

    CString Text;
    Text.Format(Load, m_GroupName);

    SetWindowText(Text);

    m_MembersDb.Open();

    PopulateList();

    return bHandled = FALSE;
}

LRESULT CMembersDlg::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
    m_MembersDb.Close();
    m_List.Detach();
    return bHandled = FALSE;
}

LRESULT CMembersDlg::OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
    OnSize();
    return bHandled = FALSE;
}

void CMembersDlg::OnSize(void)
{
    CRect r;
    m_List.GetClientRect(&r);
    m_List.SetColumnWidth(INDEX_NAME, (int)(r.Width() * OP_SYMBOL_WIDTH));
    m_List.SetColumnWidth(
        INDEX_OP,
        (int)(r.Width() * (1.0f - OP_SYMBOL_WIDTH)));
}

void CMembersDlg::OnItem(int ItemId)
{
    LVITEM Item = {0};
    Item.mask = LVIF_PARAM;
    Item.iItem = ItemId;
    Item.iSubItem = 0;
    m_List.GetItem(&Item);

    EditMember(ItemId, Item.lParam);
}

LRESULT CMembersDlg::OnListClick(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
    OnItem(((NMLISTVIEW *)pnmh)->iItem);
    return 0;
}

LRESULT CMembersDlg::OnListReturn(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
    OnItem(((NMLISTVIEW *)pnmh)->iItem);
    return 0;
}

LRESULT CMembersDlg::OnMenuContacts(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    AddNewMember();
    return 0;
}

void CMembersDlg::AddNewMember(void)
{
    CString Name;
    CString Number;
    CEOID ContactId = 0;
    PROPID PropNumberId = 0;

    HRESULT hr = Utils::ChooseContact(
        m_hWnd,
        &Name,
        &Number,
        &ContactId,
        &PropNumberId);
    if (FAILED(hr))
    {
        ATLTRACE(_T("Utils::ChooseContact failed\n"));
        return;
    }

    UINT AssignedId = 0;
    DWORD Err = m_MembersDb.Add(
        m_GroupId,
        ContactId,
        PropNumberId,
        &AssignedId);
    if (Err != ERROR_SUCCESS)
    {
        ATLTRACE(_T("Add to database failed\n"));
        return;
    }

    AddMember(AssignedId, Name, Number);
}

CString CMembersDlg::GetDisplayText(CString &Name, CString&Number)
{
    CString Text;
    if (m_DisplayNumber == true)
        Text.Format(_T("%s (%s)"), Name, Number);
    else
        Text.Format(_T("%s"), Name);

    return Text;
}

void CMembersDlg::AddMember(UINT MemberId, CString &Name, CString &Number)
{
    CString Text = GetDisplayText(Name, Number);

    LVITEM Item = { 0 };
    Item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
    Item.iItem = m_List.GetItemCount();
    Item.iSubItem = INDEX_NAME;
    Item.pszText = (LPTSTR)((LPCTSTR)Text);
    Item.iImage = 0;
    Item.lParam = MemberId;

    int NewIndex = m_List.InsertItem(&Item);
    if (NewIndex < 0)
    {
        ATLASSERT(!"InsertItem failed");
        return;
    }

    Item.mask = LVIF_TEXT;
    Item.iItem = NewIndex;
    Item.iSubItem = INDEX_OP;
    Item.pszText = (TCHAR *)OP_SYMBOL;

    m_List.SetItem(&Item);
    m_List.SelectItem(NewIndex);
    m_List.EnsureVisible(NewIndex, FALSE);
    m_List.SetFocus();
    OnSize();
}

void CMembersDlg::EditMember(int ListIndex, UINT MemberId)
{
    CEOID ContactId = 0;
    CEPROPID NumberPropId = 0;
    UINT DbIndex = 0;
    DWORD Err = m_MembersDb.GetFromId(
        MemberId,
        NULL,
        &ContactId,
        &NumberPropId,
        &DbIndex);
    if (Err == ERROR_SUCCESS)
    {
        CMemberInfoDlg dlg;
        dlg.SetContactId(ContactId);
        dlg.SetPropertyId(NumberPropId);
        int ret = dlg.DoModal();

        if (ret == IDOK)
        {
            Err = m_MembersDb.Set(
                DbIndex,
                dlg.GetContactId(),
                dlg.GetPropertyId());
            if (Err == ERROR_SUCCESS)
            {
                CString Text = GetDisplayText(dlg.GetName(), dlg.GetNumber());
                m_List.SetItemText(ListIndex, 0, Text);
            }
        }
    }
}

LRESULT CMembersDlg::OnMenuDelete(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    LVITEM Item = {0};
    Item.mask = LVIF_PARAM;
    BOOL Ret = m_List.GetSelectedItem(&Item);
    if (Ret == FALSE)
    {
        ATLTRACE(_T("No item selected to delete\n"));
        return 0;
    }

    UINT DbIndex = 0;
    DWORD Err = m_MembersDb.GetFromId(
        Item.lParam,
        NULL,
        NULL,
        NULL,
        &DbIndex);
    if (Err != ERROR_SUCCESS)
    {
        ATLTRACE(_T("Unable to get db index\n"));
        return 0;
    }

    Err = m_MembersDb.Delete(DbIndex);
    if (Err != ERROR_SUCCESS)
    {
        ATLTRACE(_T("Unable to delete from db\n"));
        return 0;
    }

    m_List.DeleteItem(Item.iItem);

    int ItemCount = m_List.GetItemCount();
    if (ItemCount > 0)
    {
        if (Item.iItem >= ItemCount)
            Item.iItem--;

        m_List.SelectItem(Item.iItem);
    }

    OnSize();

    return 0;
}

LRESULT CMembersDlg::OnMenuCancel(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    EndDialog(IDCANCEL);
    return 0;
}

void CMembersDlg::PopulateList(void)
{
    UINT i = 0;
    UINT Id = 0;
    UINT GroupId = 0;
    CEOID ContactId = 0;
    CEPROPID PropId = 0;
    DWORD Err = m_MembersDb.Get(i, &Id, &GroupId, &ContactId, &PropId);
    while (Err == ERROR_SUCCESS)
    {
        CString Name;
        CString Number;
        HRESULT hr = Utils::GetContactDetails(
            ContactId,
            PropId,
            &Name,
            &Number);
        if (SUCCEEDED(hr))
        {
            i++;

            if (GroupId == m_GroupId)
                AddMember(Id, Name, Number);
        }
        else
            m_MembersDb.Delete(i);

        Err = m_MembersDb.Get(i, &Id, &GroupId, &ContactId, &PropId);
    }

    if (m_List.GetItemCount() > 0)
    {
        m_List.SelectItem(0);
        m_List.EnsureVisible(0, FALSE);
    }
}

LRESULT CMembersDlg::OnMenuAddFromGroup(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    CGroupsDlg dlg;
    dlg.HideGroupId(m_GroupId);     // Avoid self-copy
    dlg.SetSelectMode();
    int ret = dlg.DoModal();
    if (ret == IDOK)
    {
        m_MembersDb.CopyFromId(m_GroupId, dlg.GetSelectedGroupId());

        m_List.DeleteAllItems();
        PopulateList();
    }

    return 0;
}

LRESULT CMembersDlg::OnMenuClear(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    int ret = Utils::MessageBoxRes(
        m_hWnd,
        IDR_MAINFRAME,
        IDS_CONFIRM_CLEAR,
        MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2);
    if (ret == IDNO)
        return 0;

    m_MembersDb.DeleteByGroupId(m_GroupId);
    m_List.DeleteAllItems();
    return 0;
}
